<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Cassel</title>
	<atom:link href="http://blog.davidcassel.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.davidcassel.net</link>
	<description>on Software Development and Entrepreneurism</description>
	<lastBuildDate>Thu, 29 Jan 2026 15:31:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.10</generator>
	<item>
		<title>Software Development in the Age of AI</title>
		<link>http://blog.davidcassel.net/2026/01/software-development-in-the-age-of-ai/</link>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Thu, 22 Jan 2026 17:52:53 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Industry]]></category>
		<category><![CDATA[ai]]></category>
		<guid isPermaLink="false">https://blog.davidcassel.net/?p=882</guid>

					<description><![CDATA[What does it mean to be a software developer at a time when AI can write code? I&#8217;ve been experimenting with AI tools to answer that question for myself. I&#8217;ve found what others have concluded: LLM-powered AI tools can be a great productivity boost in the right hands, but does not fully replace a skilled [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>What does it mean to be a software developer at a time when AI can write code? I&#8217;ve been experimenting with AI tools to answer that question for myself. I&#8217;ve found what others have concluded: LLM-powered AI tools can be a great productivity boost in the right hands, but does not fully replace a skilled developer.</p>



<p>Let&#8217;s cover a critical point early. If you take one thing away from this post, make it this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>The person using the tool remains responsible for the quality of the work.</p>
</blockquote>



<p>I was taught the old adage &#8220;a poor craftsman blames his tools.&#8221; That saying applies here. But what does this mean in practice? How do I, as a human developer, work with AI to get work done quickly and effectively while keeping quality up?</p>



<h2 class="wp-block-heading">Tools</h2>



<p>AI tools can be used in a variety of ways. For this experiment, I wanted to explore the boundaries, so I had AI writing code for me, not just being a sounding board. For my exploration, I used three tools.</p>



<ul class="wp-block-list">
<li>Manus (owned by Meta as of December 2025)</li>



<li>Microsoft Copilot</li>



<li>Anthropic&#8217;s Claude</li>
</ul>



<p>I used this approach with a couple projects:</p>



<ul class="wp-block-list">
<li>Building a simple CRUD web site from scratch</li>



<li>Making progress on a dormant project that was human-built</li>
</ul>



<h2 class="wp-block-heading">Roles</h2>



<h3 class="wp-block-heading">Specify</h3>



<p>Part of software development is translating business requirements into technical specifications. Vague requirements lead to guesswork about what needs to be done. Your AI will make choices that might work for you, but it&#8217;s very likely you&#8217;ll end up revising the prompt and asking it to do something different. This delays the work and wastes capacity.</p>



<p>This is true with human developers as well, of course. With a vaguely worded ticket, a developer might come back to the product owner (or whoever is providing requirements) and ask clarifying questions, or might make some assumptions. Some of these assumptions may not even be conscious ones. As developers working with AI, we need to ensure we are <em>building the right thing</em>.</p>



<p>A good prompt makes a big difference. Give the tool some context about what you&#8217;re trying to accomplish. Indicate software or library choices that have already been made to constrain the approach. Work in steps: ask the AI to review the instructions, ask clarifying questions, then propose an approach. Review the approach and provide any course correction necessary before unleashing it to write code.</p>



<p>We can think of this aspect as the latest type of abstraction. Ultimately, our work leads to high or low voltage on wires. We abstract to binary, to assembly code, to low-level and high-level languages. We use libraries and external services. Each of these allows us to focus more on what we&#8217;re trying to build instead of the details of how to build it. Providing detailed descriptions of what we want AI to accomplish provides another layer of abstraction.</p>



<h3 class="wp-block-heading">Review</h3>



<p>We can ask our AI tool for different levels of help. We could ask for a couple approaches that we then implement. We could ask it to produce a skeleton structure with comments of what needs to be filled in. With an Agentic AI, we can go as far as &#8220;Create a draft PR that….&#8221; I used this last approach for both of my experimental projects. I want a draft PR (which Github will block from merging until it has been converted to a regular PR) because I need to review what it has come up with before the work is really a candidate for inclusion in the project.</p>



<p>Regardless of what level of help we request, our next step is to evaluate what the AI tool has come up with. Does the approach make sense? Is it scalable? Is it maintainable? At least with today&#8217;s technology, AI tools make mistakes (take a close look at the picture at the top of this post). It is the job of knowledgeable professionals who use the tools to catch the mistakes before they take root.</p>



<p>These mistakes can take many forms. One simple example: I had Manus create a page that let me browse items and filter by a few criteria. Its approach was to return all data to the browser and then filter client side. That could be okay for very small data sets, but is not scalable. I had it revise the code so that filtering would happen at the database level, reducing the amount of data that gets sent to the browser. The software developer&#8217;s role here is to 1) recognize the error and 2) either directly fix the error or provide direction on how to fix the error.</p>



<p>Of course, an error can be much bigger in scope than this simple example. If the AI tool is making choices about software components, it takes knowledge and experience to consider whether those choices will be valid over time. Getting locked into an approach that causes problems a year down the road is no fun. In contrast to the Specify stage, this is where we ensure that we are <em>building the thing right</em>.</p>



<p>With a fully human developer team, this process is part of peer reviews.</p>



<h3 class="wp-block-heading">QA</h3>



<p>Assuming that the approach taken is valid, there&#8217;s still the key question of whether it works correctly. Does it meet all the acceptance criteria? Does it do the right thing with expected inputs? Does it respond gracefully to unexpected inputs? I would argue that the QA step (which is necessary regardless of how code is created) becomes even more important than ever. For a human developer using an AI tool, that developer needs to take on at least the initial QA responsibility.</p>



<h3 class="wp-block-heading">Fix What it Can&#8217;t</h3>



<p>I&#8217;d expect anyone who has tried this approach has found cases where the AI simply failed at the task. It produces the wrong thing, or code that is invalid, or just doesn&#8217;t work. I&#8217;ve gotten into loops:</p>



<ul class="wp-block-list">
<li>me: here&#8217;s the problem</li>



<li>AI: okay, try this (solution A)</li>



<li>me: that didn&#8217;t work, here&#8217;s what happened</li>



<li>AI: ah yes, of course, try this (solution B)</li>



<li>me: that didn&#8217;t work, here&#8217;s what happened</li>



<li>AI: ah yes, of course, try this (solution C)</li>



<li>me: that didn&#8217;t work, here&#8217;s what happened</li>



<li>AI: ah yes, of course, try this (solution A again!)</li>



<li>me: … we already tried that?</li>
</ul>



<p>Part of the human developer&#8217;s role is to be able to make progress from this point. Sometimes the approach is to provide a better prompt. I&#8217;ve also gotten good results having a different AI system tackle the same problem, starting from where the first one got stuck. I&#8217;ve had Claude give me good answers when Manus can&#8217;t figure something out. Sometimes we just have to apply the knowledge and skill that makes us highly valued professionals.</p>



<h2 class="wp-block-heading">Further Considerations</h2>



<p>There are a few other things that developers (and their managers) should think about.</p>



<h3 class="wp-block-heading">Security</h3>



<p>Since the rise of LLMs, this has been an important consideration. Where are your inputs going? Will they become part of future model training? For situations where you need to protect sensitive data or intellectual property, knowing the answers to these questions is important. For example, Manus is based in Singapore. Some types of data can&#8217;t be shared with Manus due to privacy restrictions. The developer needs to be very aware of such restrictions. In some cases, the solution is for a business to have its own in-house LLMs. That introduces a maintenance burden (and may not have all the capabilities of some cloud-based tools), but gives confidence that the business can control its data.</p>



<h3 class="wp-block-heading">Subscription Costs</h3>



<p>Do you know how pricing works for your AI tools? Understanding pricing structures and capabilities is important for getting the best results. If I need a throw-away script to accomplish a simple task, Copilot can often handle that. Likewise, Copilot can look at a section of code and help you understand what it does. However, it&#8217;s much less effective at bigger-picture problems. Manus has done much better with this.</p>



<p>An important element is what these tools are <em>and</em> how much access I have to them. Microsoft Copilot is part of our Microsoft 365 subscription. I have not upgraded, but this gives me broad access to GPT 5.2 model. With Manus, I have a subscription, so I get 300 tokens per day and a few thousand more per month. This is an agentic AI, so I can do things like give it a GitHub token, tell it to review an issue, ask clarifying questions, then create a PR to address the issue. I&#8217;m using the free level of Claude, but have given it access to a few directories on my laptop so that it can see (and after asking, write) files. This level gets me the Sonnet 4.5 model.</p>



<p>The options, capabilities, and pricing available at your organization are likely different. These tools are changing quickly; by the time you read this the models for each of mine may be very different. Understanding the costs and capabilities improves the efficiency you get from those tools.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>You may be wondering how far I got using Manus and friends. I was successfully able to build a reasonably simple CRUD application using a database that I&#8217;m rusty on but familiar with. For the UI, Manus introduced a library that I later learned has come into common use (I write some UI code, but I tend to focus on the back end).</p>



<p>For getting the existing project unstuck, Manus created a PR that solved an issue that had been outstanding for months (largely due to prioritization).</p>



<p>My takeaway is that a knowledgeable developer can realize productivity gains from AI. As with most things, you&#8217;ll get out of it what you put into it. A developer with sloppy habits will generate sloppy code much faster. There are cases where that can be okay &#8212; if the job is low-priority, low-impact projects where errors won&#8217;t cause problems. To build production-ready systems that people will rely on, technical leaders need to emphasize taking responsibility and pride in work done well. Focus on avoiding &#8220;slopware engineering&#8221;!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Data Agility Starts with Smart Technology Choices: How Rigid Schemas Hold You Back</title>
		<link>http://blog.davidcassel.net/2025/07/data-agility-starts-with-smart-technology-choices-how-rigid-schemas-hold-you-back/</link>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Mon, 28 Jul 2025 17:53:00 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[data modeling]]></category>
		<guid isPermaLink="false">https://blog.davidcassel.net/?p=886</guid>

					<description><![CDATA[In today’s data-driven world, agility isn’t just a competitive advantage—it’s a necessity. Organizations are increasingly building data hubs to break down data silos from across the enterprise, enabling better analytics, faster decision-making, and more responsive operations. But as any data leader knows, integrating data from diverse sources is no easy task. Data sources often express [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In today’s data-driven world, agility isn’t just a competitive advantage—it’s a necessity. Organizations are increasingly building data hubs to break down data silos from across the enterprise, enabling better analytics, faster decision-making, and more responsive operations. But as any data leader knows, integrating data from diverse sources is no easy task.</p>



<p>Data sources often express similar information differently, with varying structures, vocabularies, and labels. Figuring out a common representation of all that data is a major project in itself, before you can even start to take advantage of it. The technology choices you make around how data is stored and modeled can either enable your team to move quickly or bog them down in complexity.</p>



<p>This post explores why rigid schemas are a poor fit for modern data hubs, and how a more flexible, layered approach to data modeling can unlock true data agility.</p>



<h2 class="wp-block-heading">The Challenge of Diverse Data Sources</h2>



<p>When building a data hub, one of the most common challenges is dealing with the diversity of incoming data. Different data sources are accessed in different ways, and they each have their own way of expressing information. Field names differ, data types vary, and even the meaning of similar-looking data can shift depending on context.</p>



<p>This diversity isn’t just a technical inconvenience—it’s an obstacle to creating a single, unified view of your business. Before you can analyze or make use of the data, you need to reconcile these differences. For many organizations, that means looking in different systems for subsets of data—trying to find all the puzzle pieces needed to assemble the complete data picture. Choosing to build a unified data hub means mapping fields, aligning semantics, and often transforming the data into a common format that your systems and teams can work with.</p>



<p>This harmonization process is essential, but it’s also time-consuming and resource-intensive. And it becomes even more complex when the underlying data sources evolve. New fields appear, formats change, or entirely new systems are added to the mix. If your data platform isn’t built to accommodate this kind of change, your team will constantly be playing catch-up.</p>



<h2 class="wp-block-heading">The Pitfall of Rigid Schemas</h2>



<p>Traditional databases with a single model often rely on rigid schemas—fixed structures that define exactly what data can be stored and how it must be formatted. While this approach works well for systems with stable, predictable data structures, it becomes a major obstacle when building a data hub that needs to integrate and evolve.</p>



<p>Rigid schemas force teams to define the entire structure of the data up front. That means anticipating the type, cardinality, and relationships of every field before you can even begin ingesting data. This delays time-to-value and creates a bottleneck for innovation.</p>



<p>But in reality, not all data is equally valuable at the beginning of a project. A more agile approach is to identify a subset of the data that delivers immediate business value. Finding the key fields that support analytics, reporting, or operational decisions, then harmonizing that core data allows you to move quickly and start delivering insights that drive your business.</p>



<p>At the same time, it’s critical to preserve the rest of the data in a way that’s associated with the correct records and accessible for future use. Storing this supplementary information as JSON alongside the harmonized data provides a flexible, schema-light way to retain context without locking yourself into a rigid structure. As your understanding of the data grows or new use cases emerge, you can progressively enrich your schema without reengineering your entire pipeline.</p>



<p>This iterative approach of using a core schema and extensible raw data enables agility, adaptability, and long-term scalability.</p>



<h2 class="wp-block-heading">A More Agile Approach to Data Modeling</h2>



<p>To support agility, your data platform needs to accommodate both structure and flexibility. That means moving away from an “all-or-nothing” schema mindset and embracing an iterative approach to data modeling.</p>



<p>Start by defining a core schema that captures the most valuable and commonly used data elements. This schema should be designed to support a small number of initial use cases without trying to account for every possible variation or future need.</p>



<p>Then, instead of discarding or ignoring the rest of the data, store it in a flexible format that can be associated with the same records. JSON works well for this purpose. This allows you to retain the full context of the original data without forcing it into a rigid mold. When new requirements arise, or when deeper insights are needed, you can revisit that raw data and selectively incorporate additional fields into your harmonized model.</p>



<p>This approach offers several key benefits:</p>



<ul class="wp-block-list">
<li><strong>Faster onboarding of new data sources</strong>: You don’t need to fully model every source before you can start using it.</li>



<li><strong>Incremental schema evolution</strong>: You can adapt your model over time as business needs change.</li>



<li><strong>Preservation of context</strong>: You retain access to the original data, which can be critical for auditing, troubleshooting, or future enrichment.</li>
</ul>



<p>By combining a well-structured core with an easily accessible record of the upstream data, you create a data foundation that’s both stable and adaptable—ideal for the dynamic needs of modern enterprises.</p>



<h2 class="wp-block-heading">Technology Selection Criteria for Data Agility</h2>



<p>Choosing the right technology is critical to enabling data agility. Performance and scalability are important, but your platform also needs to support the evolving needs of your data and your business. The goal is to move quickly, adapt easily, and preserve flexibility as your requirements change.</p>



<p>Here are some key capabilities to look for when evaluating data management technologies:</p>



<ul class="wp-block-list">
<li><strong>Support for semi-structured data</strong>: Look for a platform that includes native support for formats like JSON. This allows you to retain raw data alongside structured fields, preserving context without forcing premature modeling decisions.</li>



<li><strong>Extensibility and adaptability</strong>: Your platform should make it easy to add new fields, support new data types, and evolve your schema without disrupting existing pipelines or applications.</li>



<li><strong>Integration-friendly architecture</strong>: The goal of a data hub is to have one source providing data for many services. Enabling connectivity is a key component of the project. Choose technologies that offer robust APIs and connectors while supporting common data exchange formats to simplify integration with upstream and downstream systems.</li>



<li><strong>Scalability</strong>: Even while you focus your data modeling needs on the short- to medium-term, planning for the future is essential. Your technology should scale not only in terms of data volume, but also in complexity. Over time, you may add use cases, enrich your data models, and add more sources.</li>
</ul>



<p>By prioritizing these capabilities, you’re not just choosing a tool—you’re laying the foundation for a data strategy that can grow and adapt with your organization.</p>



<h2 class="wp-block-heading">Real-World Implications</h2>



<p>The technical decision of how you approach data modeling may seem like an implementation detail, but it is central to your team&#8217;s ability to move faster, respond to change, and deliver value quickly.</p>



<p>For example, when onboarding a new data source, a rigid schema might require weeks of upfront modeling and integration work. With a more flexible approach, you can ingest the data immediately, harmonize the most important fields, and start generating insights while preserving the rest for future use.</p>



<p>This agility also supports innovation. As new opportunities emerge, your team can quickly adapt the data model to support their needs without reengineering your entire pipeline. That means faster time-to-insight, lower integration costs, and a more responsive data strategy overall.</p>



<p>In short, data agility empowers your organization to treat data as a living asset—one that evolves with your business, rather than holding it back.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>With any software project, there are some aspects that are worth getting right in the beginning. Adding security or accessibility to an almost-done project is much more complex than including them in your approach from the beginning. Likewise, a solid foundation to your data modeling strategy gives you the flexibility to move quickly, adapt to change, and evolve over time.</p>



<p>Rigid schemas and inflexible platforms slow progress. They force premature decisions, delay time-to-value, and make it harder to respond to new opportunities. By contrast, a layered, iterative approach to data modeling—harmonizing what matters now and preserving the rest for later—gives your team the tools they need to shorten time-to-value and adapt as your needs grow.</p>



<p>Choosing the right technology is a critical part of that journey. Look for platforms that support semi-structured data, enable schema evolution, and make integration seamless. With the right foundation, your data hub becomes more than a repository—it becomes a catalyst for innovation.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Winning Hearts and Minds: Strategies for Team Buy-In on Data Projects</title>
		<link>http://blog.davidcassel.net/2024/11/winning-hearts-and-minds-strategies-for-team-buy-in-on-data-projects/</link>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Fri, 22 Nov 2024 15:19:00 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Industry]]></category>
		<guid isPermaLink="false">https://blog.davidcassel.net/?p=890</guid>

					<description><![CDATA[When it comes to Big Data initiatives, selecting the right tools, platforms, and architectures is important. Often overlooked is the importance of getting your team on board with the project and the approach. Gaining buy-in across business units is critical to the success of any data project. Without it, even the best technologies can fail [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>When it comes to Big Data initiatives, selecting the right tools, platforms, and architectures is important. Often overlooked is the importance of getting your team on board with the project and the approach. Gaining buy-in across business units is critical to the success of any data project. Without it, even the best technologies can fail to deliver meaningful results.</p>



<p>I have seen the impact of buy-in—or a lack of buy-in—and how that affects project outcomes. In this post, we&#8217;ll identify the key stakeholders you need to engage, provide actionable strategies to build consensus and enthusiasm for your data project, and look at the impact of this important step.</p>



<h2 class="wp-block-heading">Why Team Buy-In Is Critical</h2>



<p>Data projects often affect multiple parts of an organization, impacting business decision-making and day-to-day workflows. While the technical and financial aspects of a project are vital, its ultimate success depends on how well it integrates into the organization’s culture and processes.</p>



<p>Here’s why buy-in matters:</p>



<ul class="wp-block-list">
<li><strong>Smooth Implementation:</strong> When stakeholders are pulling in the same direction, it’s easier to address roadblocks and adapt to challenges.</li>



<li><strong>Faster Adoption:</strong> Teams that feel involved are more likely to embrace the new tools or processes.</li>



<li><strong>Better Insights:</strong> Input from end users ensures the project aligns with real-world needs, leading to more actionable insights.</li>
</ul>



<p>Without buy-in, projects may face resistance, limited adoption, or even outright failure, wasting both time and resources.</p>



<h2 class="wp-block-heading">Key Stakeholders in a Data Project</h2>



<p>To achieve comprehensive buy-in, you need to engage all relevant stakeholders. These typically fall into four main groups:</p>



<h3 class="wp-block-heading">Business Leaders</h3>



<ul class="wp-block-list">
<li><strong>Why They Matter:</strong> They set organizational priorities and approve budgets. Their support can make or break the project.</li>



<li><strong>What They Care About:</strong> ROI, alignment with business strategy, and competitive advantage.</li>



<li><strong>What I&#8217;ve Seen:</strong> My team and I worked on a project that lacked buy-in from upper management. When the project ran into some challenges, an executive started making significant changes. These led to higher overall costs and delays in completing the project. A different client had solid buy-in from all stakeholders. When the original project champion left the company, the broad base of support allowed the project to move forward without a hitch.</li>
</ul>



<h3 class="wp-block-heading">Finance Teams</h3>



<ul class="wp-block-list">
<li><strong>Why They Matter:</strong> They control the purse strings and evaluate the financial feasibility of the project.</li>



<li><strong>What They Care About:</strong> Cost-effectiveness, long-term value, and measurable results.</li>



<li><strong>What I&#8217;ve Seen:</strong> Small projects might be able to happen under the radar, but impactful projects will have some costs. These may include software licenses, infrastructure, and outside help. Working with finance teams to align the approach with the organization&#8217;s financial plan helps get them on board. Surprises about costs, on the other hand, raise red flags.</li>
</ul>



<h3 class="wp-block-heading">Technology Teams (IT and Data Specialists)</h3>



<ul class="wp-block-list">
<li><strong>Why They Matter:</strong> They are responsible for implementing and maintaining the project.</li>



<li><strong>What They Care About:</strong> Compatibility with existing systems, scalability, and technical feasibility.</li>



<li><strong>What I&#8217;ve Seen:</strong> There are many approaches for data projects with new options becoming available all the time. Mastering new skills takes time. If the team sees that the approach being taken will be productive and they are given the time to come up to speed with new tools, they will be less likely to push back and want to revert to what they&#8217;ve done before. They need to feel confident in their ability not only to build the project, but to maintain it for the long term.</li>
</ul>



<h3 class="wp-block-heading">End Users</h3>



<ul class="wp-block-list">
<li><strong>Why They Matter:</strong> They interact directly with the tools and processes, and their participation determines adoption success.</li>



<li><strong>What They Care About:</strong> Usability, how it impacts their workflow, and training/support availability.</li>



<li><strong>What I&#8217;ve Seen:</strong> I worked on a project that had leadership, budget, and the technical team aligned. We built a solid system with lots of data and interesting reports. Unfortunately, this was a &#8220;build it and they will come&#8221; project &#8212; but they didn&#8217;t. Better engagement early on could have produced better alignment with user needs.</li>
</ul>



<h2 class="wp-block-heading">Strategies to Build Team Buy-In</h2>



<p>To create excitement and alignment around your data project, focus on involving stakeholders at every stage. Below are strategies tailored to each group:</p>



<h3 class="wp-block-heading">Involve Stakeholders Early</h3>



<ul class="wp-block-list">
<li><strong>What to Do:</strong> Begin discussions with stakeholders before making key decisions. This includes business leaders, tech teams, and end users.</li>



<li><strong>Why It Works:</strong> Early involvement helps identify concerns, align goals, and create a sense of ownership. If part of the benefit of the project is to reduce manual work, consider what that means for the people who are doing that work today. Ideally it means they can focus on higher-value, more rewarding efforts. Make sure that is communicated clearly.</li>
</ul>



<h3 class="wp-block-heading">Develop a Clear Business Case</h3>



<ul class="wp-block-list">
<li><strong>What to Do:</strong> Create a compelling narrative that connects the project to organizational goals. Use metrics to emphasize the potential ROI and benefits.</li>



<li><strong>Why It Works:</strong> A strong business case appeals to both business leaders and finance teams by tying the initiative to measurable success. When a project is tied to a compelling business need, it&#8217;s easier for all parties to grasp the value of seeing it through.</li>
</ul>



<h3 class="wp-block-heading">Create Prototypes or Pilot Projects</h3>



<ul class="wp-block-list">
<li><strong>What to Do:</strong> Implement a small-scale version of the project or a specific feature for testing. Involve end users in the process.</li>



<li><strong>Why It Works:</strong> Prototypes demonstrate value and practicality, giving stakeholders a chance to see the project in action and provide feedback. This also gives an opportunity for course correction if needs have changed. Involving end users creates anticipation as people see that the project will help them with their jobs.</li>
</ul>



<h3 class="wp-block-heading">Focus on Communication and Transparency</h3>



<ul class="wp-block-list">
<li><strong>What to Do:</strong> Regularly update the various stakeholders on progress, challenges, and milestones. Use clear, non-technical language to ensure everyone understands.</li>



<li><strong>Why It Works:</strong> Transparent communication builds trust and keeps everyone aligned toward the project’s goals.</li>
</ul>



<h3 class="wp-block-heading">Provide Training and Support</h3>



<ul class="wp-block-list">
<li><strong>What to Do:</strong> Offer tailored training sessions and resources to help end users understand the new tools and processes. Provide ongoing support to address concerns. Solicit feedback from end users &#8212; and act on it where practical.</li>



<li><strong>Why It Works:</strong> Empowering end users with knowledge reduces resistance and encourages adoption. Improving based on user feedback conveys responsiveness and a desire for the user community to be successful.</li>
</ul>



<h3 class="wp-block-heading">Celebrate Successes</h3>



<ul class="wp-block-list">
<li><strong>What to Do:</strong> Acknowledge milestones and celebrate small wins throughout the project. Recognize team members who contribute to success.</li>



<li><strong>Why It Works:</strong> Celebrating progress boosts morale and reinforces the value of the project. Hitting milestones helps business leaders and the finance team see that their investment is paying off.</li>
</ul>



<h2 class="wp-block-heading">Overcoming Common Challenges</h2>



<p>Despite best efforts, resistance can arise. Here’s how to address common issues:</p>



<ul class="wp-block-list">
<li><strong>Stakeholder Apathy:</strong> Provide regular updates &#8212; or better yet: demos &#8212; to stakeholders to show concrete progress. Emphasize the personal and organizational benefits of the project. Discuss the impact of the project not moving forward. Sometimes the right answer is that the cost exceeds the benefits. Being realistic about this early in the process builds trust.</li>



<li><strong>Technical Concerns:</strong> Run proof-of-concept sub-projects to address the concern. This might include ability to perform at scale, pace of development, security, or other concerns. Be laser focused on addressing the concern. Ensure you have the necessary expertise to give the approach a fair evaluation.</li>



<li><strong>End User Resistance:</strong> Conduct workshops and listen to concerns. Highlight how the project will make their work easier and more efficient. Consider whether the resistance comes from not addressing an important need (figure this out early!), usability, performance, or job concerns.</li>
</ul>



<h2 class="wp-block-heading">The Bottom Line</h2>



<p>Winning hearts and minds is an essential part of any Big Data initiative. These projects are often at the heart of an organization&#8217;s processes with potential for big impact. By involving stakeholders early, communicating effectively, and demonstrating the project&#8217;s value, you can build the support needed to ensure success.</p>



<p>Remember, technology may be the backbone of your project, but people are the heart. Investing time and effort into gaining team buy-in will pay dividends in smoother implementation, faster adoption, and better results.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Working with JSON in XQuery</title>
		<link>http://blog.davidcassel.net/2018/09/working-with-json-in-xquery/</link>
					<comments>http://blog.davidcassel.net/2018/09/working-with-json-in-xquery/#comments</comments>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Fri, 07 Sep 2018 18:28:11 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[xquery]]></category>
		<guid isPermaLink="false">http://blog.davidcassel.net/?p=831</guid>

					<description><![CDATA[MarkLogic supports two native languages, XQuery and JavaScript. XQuery is a very natural way to work with XML, just as JavaScript is a very natural way to work with JSON. However, sometimes it&#8217;s useful to cross over and work with JSON using XQuery or vice versa. This post has some tips on using XQuery to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>MarkLogic supports two native languages, XQuery and JavaScript. XQuery is a very natural way to work with XML, just as JavaScript is a very natural way to work with JSON. However, sometimes it&#8217;s useful to cross over and work with JSON using XQuery or vice versa. This post has some tips on using XQuery to work with JSON in memory (<a href="https://docs.marklogic.com/guide/app-dev/json#id_91533">to update JSON in the database, use the xdmp:node* functions</a>).</p>
<h2>JSON Nodes</h2>
<p>The first thing to know is that JSON that we get from the database comes in an immutable form. Specifically, that&#8217;s a JSON Node. We can directly construct JSON Nodes using constructors, like this:</p>
<pre>object-node {
Â  "a": 1,
Â  "b": 2
}</pre>
<p>If all you want to do is retrieve a node from the database, or a part of one, working with nodes is great. One of the cool things is that we can apply XPath to nodes:</p>
<pre>let $obj := object-node {
  "a": 1,
  "b": 2
}
return $obj/a</pre>
<p>This makes it easy to select a portion of a JSON document; we might do that when we pull original JSON content out of an envelope document, for instance. We can also use this to pull data that is deep in a node structure, using a path like &#8220;/envelope/instance/TopProperty/lowerProperty&#8221;.</p>
<h2>Changing</h2>
<p>If we want to edit a JSON structure, we need a different approach. There are two ways we can go about it: recursive descent over JSON nodes, or by converting to maps. I&#8217;ll give recursive descent its own post later; for now, I&#8217;ll talk about maps.</p>
<p>A map:map is a mutable key-value structure. It can be hierarchical, because the values can themselves be maps. This should sound familiar: I could give that same description for a JavaScript object. If fact, when we want to represent JSON nodes in a mutable way, the way to do it is to convert them to the map:map structure. Then we can use map:put() to change an existing value or add a new one, and map:delete() to delete an existing value. When we&#8217;re done, we can convert back to JSON to update the database or send on to a client.</p>
<pre>let $obj := object-node {
  "a": 1,
  "b": 2
}
let $map := xdmp:from-json($obj)
let $_ := map:put($map, "c", 3)
return xdmp:to-json($map)</pre>
<p>It&#8217;s worth noting here that what we get back from xdmp:from-json() isn&#8217;t just a standard map:map, but a json:object. These behave very much the same, except that 1) its default serialization is as JSON, rather than the XML that map:map uses, and 2) it maintains the key order.</p>
<p>Note that while maps are great for manipulating data, we can&#8217;t apply an XPath like we can with a JSON node.</p>
<h2>What Am I Looking At?</h2>
<p>Query Console cheerfully presents JSON data such that it looks like JSON, regardless of whether you&#8217;re looking at JSON nodes or json:objects. This can make it hard to know what exactly you&#8217;re looking at. Knowing the format of your JSON data tells you how to interact with it. You can identify an item of each representation using <code>instance of</code> tests.</p>
<pre><code>declare function local:report($item)
{
  "object node: " || $item instance of object-node() ||
  "; json:object: " || $item instance of element(json:object) ||
  "; map:entry: " || $item instance of map:map
};

let $node := object-node { "foo": "bar" }
let $obj := json:object() 
let $_ := map:put($obj, "foo", "bar")
let $json-obj := &lt;r&gt;{$obj}&lt;/r&gt;/node()
let $map := map:new(map:entry("foo", "bar"))
let $to-json := xdmp:to-json($obj)/node() (: xdmp:to-json returns a document node :)
let $to-json-map := xdmp:to-json($map)/node()
let $from-json := xdmp:from-json($node)
return (
  "node:        " || local:report($node),
  "json-obj:    " || local:report($json-obj),
  "map:         " || local:report($map),
  "obj:         " || local:report($obj),
  "to-json:     " || local:report($to-json),
  "to-json-map: " || local:report($to-json-map),
  "from-json:   " || local:report($from-json),
  "fn:data:     " || local:report(fn:data($node))
)</code></pre>
<p>Results:</p>
<pre>node:        object node: true; json:object: false; map:entry: false
json-obj:    object node: false; json:object: true; map:entry: false
map:         object node: false; json:object: false; map:entry: true
obj:         object node: false; json:object: false; map:entry: true
to-json:     object node: true; json:object: false; map:entry: false
to-json-map: object node: true; json:object: false; map:entry: false
from-json:   object node: false; json:object: false; map:entry: true
fn:data:     object node: false; json:object: false; map:entry: true</pre>
<h2>Constructing</h2>
<p>There are two ways of building JSON data. We can use the JSON node constructors directly, or we can build up maps and pass the result to xdmp:to-json(). Here&#8217;s the constructor version:</p>
<pre>object-node {
  "a": 1,
  "b": 2,
  "c": array-node {
    object-node { "fname": "Harrison", "lname": "Ford" },
    object-node { "fname": "Mark", "lname": "Hamill" },
    object-node { "fname": "Carrie", "lname": "Fisher" },
    object-node { "fname": "Natalie", "lname": "Portman" }
  }
}</pre>
<p>And here&#8217;s the method using maps:</p>
<pre>xdmp:to-json(
  json:object() =&gt;
    map:with("a", 1) =&gt; 
    map:with("b", 2) =&gt;
    map:with("c", 
      json:array() =&gt;
        json:array-with((
          json:object() =&gt; map:with("fname", "Harrison") =&gt; map:with("lname", "Ford"),
          json:object() =&gt; map:with("fname", "Mark") =&gt; map:with("lname", "Hamill"),
          json:object() =&gt; map:with("fname", "Carrie") =&gt; map:with("lname", "Fisher"),
          json:object() =&gt; map:with("fname", "Natalie") =&gt; map:with("lname", "Portman")
        ))
      )
)</pre>
<p>Personally, I find the direct constructor approach more natural. An important consideration is what you&#8217;re going to do with the structures once you have them. If you plan to modify them, go with the maps, do whatever modification you need, and then pass the finished product to xdmp:to-json &#8212; don&#8217;t convert back and forth. Likewise, if you&#8217;re constructing JSON to return to a client and won&#8217;t be persisting it in the database, stick with maps; you&#8217;ll find it runs faster.</p>
<h2>Wrap Up</h2>
<p>A little understanding goes a long way. I&#8217;ve been working with JSON data using XQuery as part of the Smart Mastering project; having gotten a better understanding of the data structures involved will let me write better code.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.davidcassel.net/2018/09/working-with-json-in-xquery/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Data Hub Framework Flows</title>
		<link>http://blog.davidcassel.net/2018/08/data-hub-framework-flows/</link>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Tue, 14 Aug 2018 04:06:02 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[data hub]]></category>
		<category><![CDATA[marklogic]]></category>
		<guid isPermaLink="false">http://blog.davidcassel.net/?p=806</guid>

					<description><![CDATA[The Data Hub Framework is a feature recently added to MarkLogic that makes it easier to gather data from a variety of sources and build a common representation across the original formats. I learned some useful things about working with the framework that I thought were worth writing down (partly so that I&#8217;ll remember them). [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>The Data Hub Framework is a feature recently added to MarkLogic that makes it easier to gather data from a variety of sources and build a common representation across the original formats. I learned some useful things about working with the framework that I thought were worth writing down (partly so that I&#8217;ll remember them).</p>
<p>My colleague at MarkLogic, Paxton Hare, started the <a href="https://github.com/marklogic/marklogic-data-hub">MarkLogic Data Hub Framework</a> project early in 2016. In the Spring of 2017, I joined him on the project. The requirements for this project were drawn from the developers who were building operational data hubs for customers.</p>
<h2>Types of Flows</h2>
<p>Paxton once told me that he thought about naming the types of flows differently: instead of &#8220;input&#8221; and &#8220;harmonize&#8221; flows, he thought &#8220;real-time&#8221; and &#8220;batch&#8221; would better describe what they do. I like the term &#8220;streaming&#8221; instead of &#8220;real-time&#8221;, to avoid confusion with <a href="https://en.wikipedia.org/wiki/Real-time_computing">real-time computing</a>.</p>
<p>Input flows are run as transforms. Some other process sends data to MarkLogic, using MLCP, the REST API, or one of the libraries built on top of the REST API, and an input flow transforms the data along the way. Input flows have no writer, because the flow itself is not responsible for persisting the data. These can be thought of as &#8220;streaming&#8221; flows, in that the flow is applied to a document between an external process sending a document and MarkLogic persisting it. These are called input flows because they mark the first point of entry into the database.</p>
<p>Harmonize flows are a process in themselves. The first step of a harmonize flow is identifying which identifiers it will work on. (These identifiers may be URIs of documents already in MarkLogic, but they could also be values to search for in a MarkLogic database or they could identify resources to pull in from an external data source.) The flow then transforms and writes each document in turn. This represents a batch approach to modifying documents. They were originally called harmonize flows because this was often the stage where documents were copied from the staging database to final, harmonizing some properties along the way.</p>
<p>When first built, the common pattern of use was that input flows were used to bring data into the staging content database, then harmonizeÂ  flows were used to turn raw data in the staging database into commonly-structured <a href="https://developer.marklogic.com/blog/envelope-design-pattern" target="_blank" rel="noopener">envelope</a> documents in the final database. This pattern became so ingrained in me originally that I didn&#8217;t notice that you didn&#8217;t need both steps. It&#8217;s perfectly reasonable to use a input flow to send data directly to the final database.</p>
<h2>Putting Flows to Work</h2>
<p>For example, I designed a data hub project to collect data from various MarkLogic web sites (www, developer, docs, training, help). Once gathered into a single database, a search service on that database would make discovery of available material across those sites much easier. (We currently have this across www, developer, docs, and some training material, but it would be beneficial to update the implementation and expand the reach.) For this project, the first key is identifying what the common attributes are across the source sites. I came up with the following:</p>
<ul>
<li>url (absolute URL, including protocol)</li>
<li>category (technical blog post, tutorial, recipe, guide, etc.; useful as facet)</li>
<li>last-updated (a date-time)</li>
<li>tags (zero or more tags, with values at the discretion of the content providers)</li>
<li>title (a string suitable for display with search results)</li>
</ul>
<p>Each data source can construct an input flow to build an envelope, with the original content stored in an <code>attachments</code> XML element or JSON property, and the above properties expressed under an <code>instance</code> element or property. (Those element/property names are chosen to be consistent with <a href="http://docs.marklogic.com/guide/entity-services">Entity Services</a>.) This data can be written directly to the final content database. No need to have an input flow to insert data, followed by a separate harmonize flow to construct the envelopes.</p>
<h2>Why Harmonize?</h2>
<p>So if an input flow can write the harmonized data to the final database, why do we need harmonize flows? These are helpful when the process of building envelopes is less straightforward. As an example, when the Documentation team publishes new content, the guides are part of a large zip file. An input flow can bring the content into MarkLogic, but since it doesn&#8217;t have a writer, it won&#8217;t be able to break it up into appropriate sized chunks. A harmonize flow can break it up in separate documents and populate the envelope properties (URL, category, and so on).</p>
<p>If your data needs to go into MarkLogic with only a self-contained set of changes, and will remain static once there, MarkLogic recommends using an input flow to send it directly to the final content database. Consider sending data to the staging database and then using a harmonize flow to bring it to the final database if you have any of the following situations:</p>
<ul>
<li>the original content has a significantly different form from what you want to make available in the final database (for instance, documents need to be split up)</li>
<li>similar to the above, if your final content database documents will be constructed from multiple input documents (as is often the case when relational data is ingested by table), send those to the staging database, then use a harmonize process to assemble the final entity documents</li>
</ul>
<h2>Iterating</h2>
<p>A harmonize flow doesn&#8217;t have to move content from one database to another; it can also be used to update content in place.</p>
<p>For the web sites hub described above, suppose that we decided to harmonize an additional property, such as author. We can write a harmonize flow that bothÂ <em>reads from</em> andÂ <em>writes to</em> the final content database. Because we store the original content in the <code>attachments</code> element of the document envelope, the flow can extract the content from the original source, add the new property, then overwrite the existing document. We&#8217;d need to write this flow for each of the input sources, assuming that the property would be found in different places in the various sources, but this would require very little coding. We&#8217;d also need to update the various input flows so that new documents would come in with the author property.</p>
<p>Once we&#8217;ve updated the input flows, how do we know which documents need the harmonize update? Here&#8217;s a part of the Entity Services document model, inside the <code>instance</code>:</p>
<pre>"info": {
Â  "title": "WebContent", 
  "version": "0.0.1"
}
</pre>
<p>When we add the author to the model, we increment the version number of the model. The harmonize flow&#8217;s collector plugin can then query against the old model version number.</p>
<h2>Wrapping Up</h2>
<p>The Data Hub Framework goes a long way to simplify the process of building an operational data hub. With a little better understanding of when to use each type of flow, your architecture will work even better.</p>
<h2>See Also</h2>
<ul>
<li><a href="https://marklogic.github.io/marklogic-data-hub/understanding/how-it-works/">Data Hub Framework: How It Works</a> (documentation)</li>
<li><a href="https://www.marklogic.com/blog/operational-data-hub-what-it-is-why-it-came-about/">Operational Data Hub: What It Is, Why It Came About</a></li>
<li><a href="https://www.marklogic.com/learn/courses/using-marklogic-data-hub-framework/">Using the MarkLogic Data Hub Framework (free hands-on training course)</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Evolution of modeling relationships in MarkLogic</title>
		<link>http://blog.davidcassel.net/2018/08/evolution-of-modeling-relationships-marklogic/</link>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Fri, 03 Aug 2018 13:35:03 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[data modeling]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[xml]]></category>
		<guid isPermaLink="false">http://blog.davidcassel.net/?p=790</guid>

					<description><![CDATA[MarkLogic, as a multi-model database, can store data both as documents and as triples. We model entities as documents. Over time, the way we&#8217;ve modeled relationships has changed. In the Beginning Prior to MarkLogic 7, relationships were modeled by including either a URI or some other identifier as an element or attribute. In most cases, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>MarkLogic, as a multi-model database, can store data both as documents and as triples. We model entities as documents. Over time, the way we&#8217;ve modeled relationships has changed.</p>
<h2>In the Beginning</h2>
<p>Prior to MarkLogic 7, relationships were modeled by including either a URI or some other identifier as an element or attribute. In most cases, we&#8217;ll also &#8220;denormalize&#8221; some information from the linked entity into the document that refers to it. In a document describing a Person entity, we might have an element like this:</p>
<pre>&lt;author uri="/book/1234.xml"&gt;
  &lt;title&gt;All the Birds in the Sky&lt;/title&gt;
  &lt;genre&gt;Science Fiction&lt;/genre&gt;
&lt;/author&gt;</pre>
<p>Here we have a relationship between a Person and a Book, where the person is the author of the book. The uri attribute provides the link. We include the title and genre elements because that enables us to search for the Person (the author) based on those pieces of information. If the application needs more information about the book, it can use the uri attribute the load the document.</p>
<p>The only downside to this is that the application needs to know not only that this relationship exists, but exactly where in the document it should look to find it.</p>
<p>For completeness, we can represent that same information using JSON:</p>
<pre>{
  "author": {
    "uri": "/book/1234.xml",
    "title": "All the Birds in the Sky",
    "genre": "Science Fiction"
  }
}</pre>
<p>These two representations are generally the same (one exception: values in attributes aren&#8217;t available for word searches).</p>
<h2>Relationships with Triples</h2>
<p>The semantic capabilities that MarkLogic has supported since version 7 give us a different way to represent relationships. Instead of the URI of the book document being in an attribute or property, we can represent the connection as a triple:</p>
<pre xml:space="preserve">Â Â &lt;sem:triple&gt;
Â Â Â Â &lt;sem:subject&gt;/person/7bfbc09d-ef7f-4976-bf16-763b70bf3995.xml&lt;/sem:subject&gt;
 Â Â Â &lt;sem:predicate&gt;http://example.org/wrote&lt;/sem:predicate&gt;
 Â Â Â &lt;sem:object&gt;/book/1234.xml&lt;/sem:object&gt;
Â Â &lt;/sem:triple&gt;
</pre>
<p>In this triple, the subject is the URI of the Person document, the object is the URI of the book document, and the predicate identifies the relationship. The triple can either be in the Person document or the Book document (<a href="http://docs.marklogic.com/guide/semantics/embedded">an unmanaged triple</a>) or stored with other triples (<a href="http://docs.marklogic.com/guide/semantics/intro#id_32716">a managed triple</a>). There are a couple benefits to this.</p>
<ol>
<li>Identifying all relationships among entities.</li>
<li>Using an ontology to ask more interesting questions.</li>
</ol>
<p>For point #1, remember that if a relationship is represented in an attribute, element, or property, the application needs to know where to look in the document to find it. With triples, however, a SPARQL query can identify all the author-book relationships very easily:</p>
<pre>select ?author ?book
where {
  ?author &lt;http://example.org/wrote&gt; ?book
}</pre>
<p>True, that requires knowing the relationship used to connect books and authors. But we can also ask, how is a Person related to other entities?</p>
<pre>select ?relationship ?entity
where {
  { &lt;/person/7bfbc09d-ef7f-4976-bf16-763b70bf3995.xml&gt; ?relationship ?entity }
union 
  { ?entity ?relationship &lt;/person/7bfbc09d-ef7f-4976-bf16-763b70bf3995.xml&gt; }
}</pre>
<p>All we need to know in this case is the entity (Person) URI that we want to inquire about. (The <a href="http://docs.marklogic.com/guide/semantics/semantic-searches#id_53812">union keyword</a> allows us to look for our entity URI in either the subject or object position of a triple.)</p>
<p>Not only does this query tell us what entities the Person entity is connected to, we&#8217;re given the predicates that connect them. One of the really cool things about using RDF triples to store relationships is that we can describe the predicates with triples, right in the database itself. For instance, the triple we showed above uses the <code>&lt;http://example.org/wrote&gt;</code> predicate. We can add a triple like this to the database:</p>
<pre>Â Â &lt;sem:triple&gt;
 Â Â Â &lt;sem:subject&gt;http://example.org/wrote&lt;/sem:subject&gt;
 Â Â Â &lt;sem:predicate&gt;rdfs:comment&lt;/sem:predicate&gt;
 Â Â Â &lt;sem:object&gt;Connects an author to a book written by the author&lt;/sem:object&gt;
Â Â &lt;/sem:triple&gt;</pre>
<p>With this in the database, we can show an end-user how the entities are connected, just by expanding our query a bit.</p>
<p>In addition, if we have a good ontology in our database, we can ask more interesting questions. Given the data shown above, our application can look for authors of Science Fiction books. We might be want to ask a broader question and find authors of all types of fiction. If our ontology recognizes that Science Fiction is a type of Fiction, we can use inference to include Science Fiction, Mystery, Historical Fiction, and other sub-types when we look for Fiction authors.</p>
<p>Using SPARQL, we can also use property paths to follow links. Suppose our data set includes &lt;reports-to&gt; links, recording the manager for each employee in an HR database. We can find one person&#8217;s boss with a simple query:</p>
<pre>select ?boss
where {
Â  &lt;http://example.com/person/ann&gt; &lt;reports-to&gt; ?boss
}</pre>
<p>Suppose we want to find the chain of managers from Ann all the way to the CEO. With the original style of recording URIs in an element, attribute, or JSON property, we&#8217;d need to retrieve Ann&#8217;s manager, do another query to find that person&#8217;s manager, and so on. We&#8217;d need the same process with a relational structure. But with SPARQL, we can add a single character to the query above: &#8220;+&#8221;.</p>
<pre>select ?boss 
where {
 Â &lt;http://example.com/person/ann&gt; &lt;reports-to&gt;+ ?boss
}</pre>
<p>The &#8220;+&#8221; says to follow that predicate 1 more times and returns a list of managers from Ann all the way to the top. SPARQL provides several &#8220;<a href="https://www.w3.org/TR/sparql11-query/#propertypaths">property paths</a>&#8221; that enable more interesting queries for exploring a data set.</p>
<h2>Template Driven Extraction</h2>
<p>MarkLogic 9 adds <a href="http://developer.marklogic.com/learn/template-driven-extraction">Template Driven Extraction</a> (TDE). Using TDE, we can pull information from documents directly into indexes, accessible from either SQL or SPARQL queries. We can do this without changing the original document structure itself. This approach lets us connect our XML and JSON documents to a full ontology without running transforms.</p>
<h2>Wrapping Up</h2>
<p>The triples model allows for discoverable connections among entities. The biggest challenge is to make use of this representational power in a useful way, by selecting predicates that link into a relevant ontology. (I like to use <a href="http://dbpedia.org/fct/">http://dbpedia.org/fct/</a> to help find relevant IRIs.) This only applies when your application has an ontology to connect to, but with that or without it, storing connections among entities, along with descriptions of those connections, allows data and its meaning to exist side-by-side. This advantage, plus the discoverability of relationships, is a clear improvement that will give your applications more powerful search.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Building a MarkLogic Data Model</title>
		<link>http://blog.davidcassel.net/2015/08/building-a-marklogic-data-model/</link>
					<comments>http://blog.davidcassel.net/2015/08/building-a-marklogic-data-model/#comments</comments>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Thu, 06 Aug 2015 16:53:25 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[data modeling]]></category>
		<category><![CDATA[marklogic]]></category>
		<guid isPermaLink="false">http://blog.davidcassel.net/?p=713</guid>

					<description><![CDATA[This post is an excerpt from a book I&#8217;m working on: MarkLogic for Node.js Developers. This section is part of a chapter on Data Modeling, falling after a comparison to relational database modeling and a discussion of denormalization. The goal is to address the question of what should be a document in MarkLogic. The next [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><em>This post is an excerpt from a book I&#8217;m working on: MarkLogic for Node.js Developers. This section is part of a chapter on Data Modeling, falling after a comparison to relational database modeling and a discussion of denormalization. The goal is to address the question of what should be a document in MarkLogic. The next section illustrates these points using <a href="https://github.com/marklogic/marklogic-samplestack" target="_blank">Samplestack</a> as a case study. Feedback welcome.Â </em></p>
<h3><a name="_Toc300474065"></a>Building a Data Model</h3>
<p>There are severalÂ factors to consider when deciding what to include in a document.</p>
<p><em>Document databases can hold many types of documents.</em></p>
<p>In a document database, documents that represent different types of entities can sit side by side. A book database might have separate documents for books, authors, and publishers, each containing the bulk of information related to that type.</p>
<p><em>A document is the unit of search.</em></p>
<p>When doing a search against a MarkLogic database, the typical goal is to identify which documents match a particular query. Understanding what an applicationâ€™s users will want to search for informs the types of documents you should have.</p>
<p><em>Include what will be searched for. </em></p>
<p>When considering a book database, a user might want to search for books by a particular publisher, but will probably not be looking for books published by a company based in a particular region, or founded in a certain year. Such information can be left out of the book document â€“ it will not contribute to search, so there is no benefit to repeating it. Repeating the publisherâ€™s name in book documents makes more sense. Data that is more helpful when searching for publishers will be included in publisher documents.</p>
<p><em>Donâ€™t repeat what will be updated often.</em></p>
<p>Pieces of data that will change often should be normalized. For example, a publishing companyâ€™s name will not change often, and therefore could be denormalized into other documents if searching on it is important.</p>
<p><em>Dynamically calculate values that will change quickly.</em></p>
<p>How many books has an author sold? The answer is the sum of the sales of each book the author has published. The essential data is the per-book sales. The total will change frequently; storing the total will lead to frequent updates and a need to work at the application level to ensure the number stays correct. Conversely, the total is easy to calculate at run-time and can be done very quickly using indexes.</p>
<p><em>Size documents appropriately.</em></p>
<p>In MarkLogic, the ideal document size is in the range of 10 kilobyte to 1 megabyte. Larger documents take time to read from disk when they need to be retrieved. Very small documents are less efficient, since there is some overhead introduced for each document.</p>
<p><em>Choose JSON or XML, or a mix.</em></p>
<p>In some ways, the choice between JSON and XML is a matter of preference. For a Node.js developer, JSON is a very natural choice, as JSON and JavaScript are so closely related. This book will focus on JSON.</p>
<p>If there is a starting data set that uses XML, the developer may choose to keep it that way in the database, but transform to JSON in response to requests for data.</p>
<p>There are some differences in what can be represented in JSON versus XML. XML is good for text that will be marked up. For instance, consider a document that will be passed to an entity extraction engine to identify person names, locations, organizations, dates, and other information. In some cases, we just want to know that these things exist within a document, in which case we can store it in JSON. However, if we want to mark up the document inline, so that we can later look for entities near each other, XML handles this well. XML also allows for attributes, which describe elements.</p>
<hr />
<p><code>&lt;content&gt;&lt;person&gt;David Cassel&lt;/person&gt; started working for &lt;company&gt;MarkLogic&lt;/company&gt; in &lt;date start=â€2009-01-01â€ end=â€2009-12-31â€&gt;2009&lt;/date&gt;. Before that, he worked for &lt;company&gt;Lockheed Martin&lt;/company&gt;.&lt;/content&gt;</code><br />
Figure 6: Example XML data showing markup</p>
<hr />
<p>Overall, XML is an expressive format for representing content (text in a hierarchical structure), while JSON is good for data â€“ key/value pairs, arrays, and other data that consists of scalar data at various levels of the document hierarchy.</p>
<p><em>MarkLogic is schema-agnostic. </em></p>
<p>Relational databases require a schema to describe data. XML documents stored in MarkLogic may be required to adhere to an XML schema, but this is optional. In most cases, no formal schema is used and documents with multiple, informal schemas exist within a database. This flexibility is what is meant by schema-agnostic. MarkLogic contrasts that with â€œschemalessâ€ databases, which do not provide the option to require a schema.</p>
<p>There is no widely accepted standard for JSON schemas at this time and MarkLogic does not support requiring a schema for JSON documents.</p>
<p><em>MarkLogic supports two-stage queries.</em></p>
<p>Although MarkLogic documents are typically denormalized, sometimes a query requires some data from one type of document to query a different type of document. Data modeling in MarkLogic seeks to minimize this, but when necessary, an application can do a two-stage query. This is effectively a join and avoided where practical for the same reasons it is problematic for relational databases â€“ two stage queries are necessarily slower than a single-stage query.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.davidcassel.net/2015/08/building-a-marklogic-data-model/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Focusing on the community</title>
		<link>http://blog.davidcassel.net/2014/09/focusing-on-the-community/</link>
					<comments>http://blog.davidcassel.net/2014/09/focusing-on-the-community/#comments</comments>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Fri, 26 Sep 2014 18:40:01 +0000</pubDate>
				<category><![CDATA[Career]]></category>
		<category><![CDATA[marklogic]]></category>
		<guid isPermaLink="false">http://blog.davidcassel.net/?p=696</guid>

					<description><![CDATA[I&#8217;ve got a new focus &#8212; I&#8217;m now the Developer Community Manager for MarkLogic. I&#8217;m really excited about this &#8211;Â it&#8217;s a chance to work with a growing community of great developers. My new goal, in a nutshell, is to increase the community of developers who know how to work with MarkLogic. I&#8217;ve got a bunch [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve got a new focus &#8212; I&#8217;m now the Developer Community Manager for MarkLogic. I&#8217;m really excited about this &#8211;Â it&#8217;s a chance to work with a growing community of great developers.</p>
<p>My new goal, in a nutshell, is to increase the community of developers who know how to work with MarkLogic. I&#8217;ve got a bunch of ideas, involving outreach, learning materials, field-developed tools, and so on. Several people have been kind enough to share with me what they&#8217;d like to see. I welcome that, keep it coming.</p>
<p>My publishing efforts will shift largely to the <a href="http://developer.marklogic.com" target="_blank">MarkLogic Developer site</a>. I&#8217;ll still write something up here sometimes, but look for more to happen over there.</p>
<p>I look forward to working with the larger developer community in the years to come!</p>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.davidcassel.net/2014/09/focusing-on-the-community/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>Memoization in XQuery</title>
		<link>http://blog.davidcassel.net/2014/07/memoization-in-xquery/</link>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Mon, 28 Jul 2014 21:33:32 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[xquery]]></category>
		<guid isPermaLink="false">http://blog.davidcassel.net/?p=686</guid>

					<description><![CDATA[Memoization is tracking partial solutions so that they don&#8217;t have to be recalculated. A good example of where this is handy is the Fibonacci sequence. You may remember that the definition of this is: F(n) = F(nÂ -1) + F(nÂ &#8211; 2) F(1) = 1 F(2) = 1 Clearly, this is a recursive function. Let&#8217;s take a [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a title="Wikipedia" href="http://en.wikipedia.org/wiki/Memoization" target="_blank">Memoization</a> is tracking partial solutions so that they don&#8217;t have to be recalculated. A good example of where this is handy is the <a href="http://en.wikipedia.org/wiki/Fibonacci_number" target="_blank">Fibonacci sequence</a>. You may remember that the definition of this is:</p>
<p>F(<i>n</i>) = F(<i>n</i>Â -1) + F(<i>n</i>Â &#8211; 2)<br />
F(1) = 1<br />
F(2) = 1</p>
<p>Clearly, this is a recursive function. Let&#8217;s take a look at the naive implementation:</p>
<p><script src="https://gist.github.com/9a21db841067eed34c5e.js"></script></p>
<p>The good news is that we get the right answer.</p>
<p>local:fib(10) =&gt; 55</p>
<p>The bad news is that this is a seriously inefficient way to do it. Why? Let&#8217;s look at what happens when we calculate local:fib(10)</p>
<p>F(10) = F(9) + F(8)</p>
<p>As we calculate F(9), we&#8217;ll figure out F(8) and F(7). Our function will recurse through these until it has an answer, bringing us to</p>
<p>F(10) = 34 + F(8)</p>
<p>Now we recurse on F(8) to find that value. But wait, we already calculated F(8) as part of finding the value of F(9)! We need a way to keep track of the values we&#8217;ve already calculated so that we don&#8217;t have to recomputed them.</p>
<p>Enter the map.Â Maps, or associative arrays, are a tool available in many programming languages, including MarkLogic&#8217;s XQuery. While not part of the XQuery 3.0 standard, this is a tool you want in your belt.Â You&#8217;ll findÂ <a title="MarkLogic maps" href="http://docs.marklogic.com/guide/app-dev/hashtable#chapter" target="_blank">some great documentation on the mapping operators</a>; my goal here is to show a technique where maps will help with your runtime performance.</p>
<p>Let&#8217;s try another version of that function.</p>
<p><script src="https://gist.github.com/78aa858a0aac9c9f2fc3.js"></script></p>
<p>The base case remains the same, but when we&#8217;re computing other values, we put them into the map as they are calculated.</p>
<h2>Performance</h2>
<p>Let&#8217;s see what kind of difference this makes. I set up each of these functions in Query Console and called each function with n = 20 while looking at the Profile tab.</p>
<p>Naive version: 85,353 expressions; about 0.046 seconds.</p>
<p>Improved version: 354 expressions; about 0.00034 seconds.</p>
<p>That&#8217;s two orders of magnitude fewer expressions that needed to be run, reducing the run time by a similar amount.</p>
<p>This approach is useful for problems where:<br />
1. you have a recursive solution<br />
2. where some of the calculations would otherwise be repeated</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Loading JSON into MarkLogic 7</title>
		<link>http://blog.davidcassel.net/2014/06/loading-json-into-marklogic-7/</link>
					<comments>http://blog.davidcassel.net/2014/06/loading-json-into-marklogic-7/#comments</comments>
		
		<dc:creator><![CDATA[Dave Cassel]]></dc:creator>
		<pubDate>Mon, 30 Jun 2014 22:04:38 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[ml7]]></category>
		<category><![CDATA[mlcp]]></category>
		<category><![CDATA[rest api]]></category>
		<guid isPermaLink="false">http://blog.davidcassel.net/?p=679</guid>

					<description><![CDATA[This post shows how to ingest JSON into MarkLogic 7 using mlcp. Unlike many, this one is very specific to MarkLogic 7. Since the release of MarkLogic 6,Â MarkLogic Content Pump (mlcp) has been the supported tool for importing, exporting, and copying content. One feature that&#8217;s missing from it is the ability to load JSON files [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>This post shows how to ingest JSON into MarkLogic 7 using mlcp. Unlike many, this one is very specific to MarkLogic 7.</p>
<p>Since the release of MarkLogic 6,Â MarkLogic Content Pump (mlcp) has been the supported tool for importing, exporting, and copying content. One feature that&#8217;s missing from it is the ability to load JSON files without having them stored as text files. To expand on that, let me point out that MarkLogic 7 is part of a transition in how MarkLogic handles JSON files.</p>
<table class="border: 1px solid black;">
<tbody>
<tr>
<th>MarkLogic Version</th>
<th>handles JSON as</th>
</tr>
<tr>
<td>5</td>
<td>text</td>
</tr>
<tr>
<td>6, 7</td>
<td>quietly converted to XML</td>
</tr>
<tr>
<td>8</td>
<td>native type</td>
</tr>
</tbody>
</table>
<p>In MarkLogic 5, JSON documents are stored as text. As with any text document, that lets you do word searches, but you&#8217;re not able to use the structure.</p>
<p>In MarkLogic 6 and 7, you can load JSON using the REST API and MarkLogic quietly converts it to an XML format. When you request the document back, MarkLogic quietly converts it back toÂ JSON. The reason for this is that handling JSON was a goal for MarkLogic 6, but it&#8217;s done at the REST API level &#8212; internally, actual JSON would just be text, preventing us from building indexes and otherwise working with the structure. By converting it to XML internally, we can do much more with it.</p>
<p>In MarkLogic 8, JSON is planned to be a native type. I tested loading JSON with mlcp today on an ML8 development build, and mlcp loads JSON as native content, meaning that the structure is accessible without having to do anything special.</p>
<h2>Ingest via REST API</h2>
<p>We can ingest JSON and have it transparently converted by POSTing them to the REST API. Here&#8217;s how to load a directory of JSON documents.</p>
<pre>for f in ~/data/json-data/*.json; do
curl --anyauth --user admin:admin -X POST -d@$f -i \
Â  -H "Content-type: application/json" \
Â  'http://localhost:8040/v1/documents?extension=json&amp;directory=/content/';
done</pre>
<p>That works great, but for larger amounts of data, you lose out on mlcp&#8217;s ability to parallelize the workload.</p>
<h2>Ingest via MLCP</h2>
<p>MarkLogic&#8217;s documentation describes <a title="Transforming Content During Ingestion" href="http://docs.marklogic.com/guide/ingestion/content-pump#id_82518" target="_blank">how to use a transform with mlcp</a>. Here&#8217;s a simple transform that applies MarkLogic&#8217;s <a href="http://docs.marklogic.com/json:transform-from-json" target="_blank">json:transform-from-json()</a> function:</p>
<p><script src="https://gist.github.com/e892bfe8f016eea34045.js"></script></p>
<p>And here&#8217;s the call to have mlcpÂ use it:</p>
<p><script src="https://gist.github.com/800327120e9abaf0abc4.js"></script></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.davidcassel.net/2014/06/loading-json-into-marklogic-7/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
	</channel>
</rss>
